﻿using InfoPathHelpers.TemplateExplorer;
using InfoPathHelpers.TemplateExplorer.Definitions;
using Microsoft.Office.InfoPath;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

namespace InfoPathHelpers.DataSources
{
    public static class DataSourceInitializer
    {
        /// <summary>
        /// Initializes all XmlFileAdapters that are not initialized on load.
        /// </summary>
        /// <param name="formContext">The form context for which to intialize data sources.</param>
        /// <returns>False if any dataSource could not be initialized (subsequent dataSources are not initialized); 
        /// otherwise true.</returns>
        public static bool Initialize(FormContext formContext)
        {
            return Initialize(formContext, null, null);
        }

        /// <summary>
        /// Initilizes the specified XmlFileAdapter if it was not initialized on load.
        /// </summary>
        /// <param name="formContext">The form context for which to intialize data sources.</param>
        /// <param name="dataSourceName">The name of the data source to initialize.</param>
        /// <returns>False if any dataSource could not be initialized (subsequent dataSources are not initialized); 
        /// otherwise true.</returns>
        public static bool Initialize(FormContext formContext, string dataSourceName)
        {
            return Initialize(formContext, dataSourceName, null, null);
        }

        /// <summary>
        /// Initializes all XmlFileAdapters that are not initialized on load.
        /// </summary>
        /// <param name="formContext">The form context for which to intialize data sources.</param>
        /// <param name="e">The LoadingEventArgs for the loading event.</param>
        /// <param name="failureView">The name of the view to switch to if a data source could not be loaded.</param>
        /// <returns>False if any dataSource could not be initialized (subsequent dataSources are not initialized); 
        /// otherwise true.</returns>
        public static bool Initialize(FormContext formContext, LoadingEventArgs e, string failureView)
        {
            var ManifestExplorer = new ManifestExplorer(formContext);

            foreach (var DataSource in ManifestExplorer.GetXmlFileAdapters())
            {
                if(!Initialize(formContext, DataSource, e, failureView))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// Initilizes the specified XmlFileAdapter if it was not initialized on load. This overload should be called from the form loading event.
        /// </summary>
        /// <param name="formContext">The form context for which to intialize data sources.</param>
        /// <param name="dataSourceName">The name of the data source to initialize.</param>
        /// <param name="e">The LoadingEventArgs for the loading event.</param>
        /// <param name="failureView">The name of the view to switch to if a data source could not be loaded.</param>
        /// <returns>False if any dataSource could not be initialized (subsequent dataSources are not initialized); 
        /// otherwise true.</returns>
        public static bool Initialize(FormContext formContext, string dataSourceName, LoadingEventArgs e, string failureView)
        {
            var ManifestExplorer = new ManifestExplorer(formContext);

            var DataSource = ManifestExplorer.GetXmlFileAdapters()
                .Find(delegate(XmlFileAdapterDefinition x) 
                {
                    return x.Name == dataSourceName;
                });

            if (DataSource == null)
            {
                throw new ArgumentException(dataSourceName + " does not exist.");
            }

            return Initialize(formContext, DataSource, e, failureView);
        }

        private static bool Initialize(FormContext formContext, XmlFileAdapterDefinition dataSource, LoadingEventArgs e, string failureView)
        {
            if (dataSource.IsIncludedInTemplate || !dataSource.IsInitialzedOnLoad)
            {
                if (File.Exists(dataSource.Path))
                {
                    formContext.DataSources[dataSource.Name].QueryConnection.Execute();
                }
                else
                {
                    if (e != null)
                    {
                        e.SetDefaultView(failureView);
                    }
                    return false;
                }
            }
            return true;
        }
    }
}
